/* Yet Another Experimental Software Renderer
 *
 * Copyright (c) 2010 Pawel "Hery" Dziepak
 */

#include "function_input.h"
#include "engine.h"

#include <SDL.h>

using namespace yaesr;

class sdl_output : public pixel_output {
public:
	sdl_output(int w, int h) : pixel_output(w, h) {
		SDL_WM_SetCaption("Yaesr", "Yaesr");
		surface = SDL_SetVideoMode(w, h, 32, SDL_SWSURFACE);
		SDL_LockSurface(surface);
	}

	void flush() {
		SDL_UnlockSurface(surface);
		SDL_UpdateRect(surface, 0, 0, width, height); 
	}

	void put_pixel(int x, int y, color pixel_color) {
		if (x < 0 || y < 0 || x > width-1 || y > height-1)
			return;

		int bpp = surface->format->BytesPerPixel;
		Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
		Uint32 pixel = pixel_color.to_int32();
		*(Uint32 *)p = pixel;
	}

	void clear(color pixel_color) {
		SDL_FillRect(surface, NULL, pixel_color.to_int32());
	}
private:
	SDL_Surface *surface;
};

int main(int argc, char *argv[]) {
	(argc);
	(argv);

	SDL_Init(SDL_INIT_VIDEO);
	atexit(SDL_Quit);
	
	engine *yeng = new engine;

	yeng->set_vertex_shader(new vertex_shader_impl);
	yeng->set_hull_shader(new hull_shader_impl);

	domain_shader_impl *dsi = new domain_shader_impl;
	yeng->set_domain_shader(dsi);
	dsi->displace = new bilinear_sampler(color_texture::load_bmp("texture.bmp"));

	yeng->set_geometry_shader(new geometry_shader_impl);

	pixel_shader_impl *psi = new pixel_shader_impl;
	psi->set_texture(new bilinear_sampler(color_texture::load_bmp("texture.bmp")));

	pixel_shader_impl2 *psi2 = new pixel_shader_impl2;
	yeng->set_pixel_shader(psi2);

	sdl_output *sdl = new sdl_output(1024, 768);
	sdl->clear(color(0.0, 0.0, 0.0, 0.0));
	
	yeng->set_output(sdl);
	yeng->launch();

	function_input *input = yeng->get_input<function_input>();

	input->begin(triangle_strip);

	input->set_vertex(0.0, 0.7, 0.0);
	input->set_color(1.0, 0.0, 1.0, 0.0);
	input->set_texccord(0.0, 0.0);

	input->set_vertex(-0.5, 0.7, 0.8);
	input->set_color(1.0, 1.0, 0.0, 0.0);
	input->set_texccord(1.0, 0.0);

	input->set_vertex(0.0, -0.5, 0.0);
	input->set_color(1.0, 1.0, 0.5, 0.5);
	input->set_texccord(0.0, 1.0);

	input->set_vertex(-0.5, -0.5, 0.8);
	input->set_color(1.0, 1.0, 1.0, 1.0);
	input->set_texccord(1.0, 1.0);

	input->end();

	yeng->set_pixel_shader(psi);

	input->begin(triangle_strip);

	input->set_vertex(-0.02, 0.0, -0.3);
	input->set_texccord(0.0, 0.0);

	input->set_vertex(-0.5, 0.1, -0.3);
	input->set_texccord(0.2, 0.0);

	input->set_vertex(0.2, -0.5, 0.4);
	input->set_texccord(0.0, 0.2);

	input->set_vertex(-0.5, -0.5, 0.7);
	input->set_texccord(0.2, 0.2);

	input->end();

	sdl->flush();

	SDL_Event event;
	bool running = true;
	while(running) {
		while( SDL_WaitEvent( &event ) ) {
			switch( event.type ) {
			case SDL_QUIT:
				return 0;
				break;
			}
		}
	}

	return 0;
}


